package cn.wp.ewallet.wallet.service.impl;

import cn.wp.common.core.dao.JdbcSupportTemplate;
import cn.wp.common.core.dao.SqlString;
import cn.wp.common.core.dto.WpResult;
import cn.wp.common.core.exception.WpBizException;
import cn.wp.common.core.id.Id;
import cn.wp.common.core.web.WpUserContext;
import cn.wp.ewallet.wallet.extension.constant.EwalletWalletConstant;
import cn.wp.ewallet.wallet.extension.constant.ExchangeConstant;
import cn.wp.ewallet.wallet.model.dto.WalletShqcAccountInfoDto;
import cn.wp.ewallet.wallet.model.entity.UserCollectDo;
import cn.wp.ewallet.wallet.model.entity.UserOrderDo;
import cn.wp.ewallet.wallet.model.entity.UserPublishDo;
import cn.wp.ewallet.wallet.service.*;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserOrderServiceImpl extends BaseServiceImpl<UserOrderDo> implements UserOrderService {
    public UserOrderServiceImpl(JdbcSupportTemplate jdbcSupportTemplate) {
        super(jdbcSupportTemplate);
    }

    @Autowired
    UserPublishService publishService;
    @Autowired
    WalletInfoService walletInfoService;
    @Autowired
    private UserCollectService userCollectService;
    @Autowired
    private AccountInfoService accountInfoService;
    @Autowired
    private JdbcSupportTemplate jdbcSupportTemplate;


    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public WpResult create(String publishId, String collectType, BigDecimal count, String transPwd) {
        UserPublishDo publish = publishService.select("PUBLISH_ID = '" + publishId + "'").get(0);
        if (publish.getType() == 0) {
            if (Strings.isBlank(transPwd)) {
                return new WpResult().failure(EwalletWalletConstant.CHECK_TRANSPWD_NULL_CODE, "交易密码为空");
            }
            //校验交易密码
            if (!walletInfoService.checkTransPwd(transPwd)) {
                return new WpResult().failure(EwalletWalletConstant.CHECK_TRANSPWD_FAILED_CODE, "交易密码校验失败");
            }
        }
        if (count.compareTo(publish.getMax()) > 0) {
            return new WpResult().failure(ExchangeConstant.PUBLISH_IS_DOWN_EOR, "最大购买额为" + publish.getMin() + "，不能下单");
        } else if (count.compareTo(publish.getMin()) < 0) {
            return new WpResult().failure(ExchangeConstant.PUBLISH_IS_DOWN_EOR, "最小购买额为" + publish.getMin() + "，不能下单");
        }
        if (!publish.isStatus()) {
            return new WpResult().failure(ExchangeConstant.PUBLISH_IS_DOWN_EOR, "已完成指标，不能下单");
        }
        BigDecimal remain = publish.getCount().subtract(publish.getCounted()).subtract(publish.getFrenze());
        UserOrderDo order = new UserOrderDo();
        order.setCount(count);
        if (publish.getType() == 0) {
            //检测出售数据余额
            if (remain.compareTo(order.getCount()) < 0) {
                return new WpResult().failure(ExchangeConstant.PUBLISH_REMIND_LACK_EOR, "卖方标池余额不足");
            }
            //购买需求对应出售顶单
            order.setType(1);
        } else {
            if (remain.compareTo(order.getCount()) < 0) {
                return new WpResult().failure(ExchangeConstant.ORDER_RG_REMIND_EOR, "已超出对方发布指标");
            }
            WalletShqcAccountInfoDto walletShqcAccountInfo = walletInfoService.getWalletShqcAccountInfo();
            //检测购买人（指当前创建出售订单的人）账户余额
            if (walletShqcAccountInfo.getAvailableShqc().compareTo(order.getCount()) < 0) {
                return new WpResult().failure(EwalletWalletConstant.CHECK_AMOUNT_FAILED_CODE, "账户余额不足");
            }
            order.setType(0);
            // 直接扣除用户得 SHQC余额
            accountInfoService.exchange(walletShqcAccountInfo.getAccountId(), count.negate());
        }

        // 根据 collectType 获取收款信信息
        // 买币时 获取卖家的收款信息
        // 当卖币时 获取自己的收款信息
        List<UserCollectDo> collectDos = new ArrayList<UserCollectDo>();
        if (order.getType() == 0) {
            collectDos = userCollectService.select("user_id='" + publish.getUserId() + "'" +
                    " and type = '" + collectType + "'");
            if (collectDos == null || collectDos.size() < 1) {
                return new WpResult().failure(ExchangeConstant.COLLECT_TYPE_NULL_EOR, "卖家收款方式不存在");
            }
        } else {
            collectDos = userCollectService.select("user_id='" + WpUserContext.get().getId() + "'" +
                    " and type = '" + collectType + "'");
            if (collectDos == null || collectDos.size() < 1) {
                return new WpResult().failure(ExchangeConstant.COLLECT_TYPE_NULL_EOR, "请添加您对应的收款方式");
            }
        }
        UserCollectDo collectDo = collectDos.get(0);
        order.setOrderId(Id.createOrderId());
        order.setUserId(WpUserContext.get().getId());
        order.setCreateTime(System.currentTimeMillis());
        order.setStatus(1);
        order.setPayType(collectDo.getType());
        order.setCollectAccount(collectDo.getCollectAccount());
        order.setCollectNo(collectDo.getCollectNo());
        order.setImg(collectDo.getImg());
        order.setCount(count);
        order.setPrice(publish.getPrice());
        order.setPublishId(publishId);
        // 冻结标的需求余额
        publishService.freeze(publishId, count);
        this.insert(order);
        return new WpResult().success(order);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void cancel(String id, String status) {
        UserOrderDo order = this.select("order_id = '" + id + "' and status in (1,2)").get(0);
        // 购买
        if (order.getType() == 0) {
            if (order.getStatus().equals(0)) {
                WpBizException.NEW("交易已完成,如有疑问请联系客服处理");
            } else if (order.getStatus().equals(3) || order.getStatus().equals(5) || order.getStatus().equals(6)) {
                // 3 超时取消 5 订单创建者取消 6 系统取消
                WpBizException.NEW("交易已取消,如有疑问请联系客服处理");
            } else if (order.getStatus().equals(1)) { // 未转账
                // 设置订单状态 5
                this.execute("update user_order set status = '" + status + "' where order_id = '" + id + "'");
                // 设置标的冻结解冻
                publishService.back(order.getPublishId(), order.getCount());
            } else if (order.getStatus().equals(2)) {
                if (status.equals(6)) { // 已转账未确认，系统取消
                    // 设置订单状态为系统取消
                    this.execute("update user_order set status = '" + status + "' where order_id = '" + id + "'");
                    // 设置标的冻结解冻
                    publishService.back(order.getPublishId(), order.getCount());
                } else {
                    WpBizException.NEW("交易已付款,如有疑问请联系客服处理");
                }
            }
        } else {
            if (order.getStatus().equals(0)) {
                WpBizException.NEW("交易已完成,如有疑问请联系客服处理");
            } else if (order.getStatus().equals(3) || order.getStatus().equals(5) || order.getStatus().equals(6)) {
                // 3 超时取消 5 订单创建者取消 6 系统取消
                WpBizException.NEW("交易已取消,如有疑问请联系客服处理");
            } else if (order.getStatus().equals(1)) { // 未转账
                this.execute("update user_order set status = '" + status + "' where order_id = '" + id + "'");
                // 将币退回给卖家
                accountInfoService.exchange(accountInfoService.shqcAccountId(order.getUserId()), order.getCount());
                // 求购方 的解冻
                publishService.back(order.getPublishId(), order.getCount());
            } else if (order.getStatus().equals(2)) {
                if (status.equals(6)) { // 已转账未确认，系统取消
                    // 设置订单状态为系统取消
                    // 设置订单状态 5
                    this.execute("update user_order set status = '" + status + "' where order_id = '" + id + "'");
                    // 将币退回给卖家
                    accountInfoService.exchange(accountInfoService.shqcAccountId(order.getUserId()), order.getCount());
                    // 求购方 的解冻
                    publishService.back(order.getPublishId(), order.getCount());
                } else {
                    WpBizException.NEW("交易已付款,如有疑问请联系客服处理");
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void pay(String id) {
        UserOrderDo order = this.select("order_id = '" + id + "'" + (StringUtils.isNotEmpty(WpUserContext.get().getId()) ? "and user_id = '" + WpUserContext.get().getId() + "'" : "")).get(0);
        if (order.getStatus().equals(1)) {
            this.execute("update user_order set status = '2' where order_id = '" + id + "'");
        } else if (order.getStatus().equals(2)) {
            WpBizException.NEW("请勿重复支付");
        } else if (order.getStatus().equals(0)) {
            WpBizException.NEW("订单已完结");
        } else if (order.getStatus() > 2) {
            WpBizException.NEW("交易已取消");
        }
    }

    @Override
    public void finish(String id) {
        UserOrderDo order = this.select("order_id = '" + id + "'").get(0);
        if (order.getStatus().equals(1)) {
            WpBizException.NEW("订单尚未付款");
        } else if (order.getStatus().equals(2)) {
            List<UserPublishDo> select = publishService.select("user_id = '" + WpUserContext.get().getId() + "' and publish_id = '" + order.getPublishId() + "'");
            if (order.getType().equals(0)) {
                //出售需求则由出售方确认收款
                if (select == null) {
                    WpBizException.NEW("非出售方不可确认");
                }
                // 出售方完成，冻结转为已完成
                publishService.finish(order.getPublishId(), order);
                // 购买方币增加
                accountInfoService.exchange(accountInfoService.shqcAccountId(order.getUserId()), order.getCount());
            } else {
                if (!order.getUserId().equals(WpUserContext.get().getId())) {
                    WpBizException.NEW("非出售方不可确认");
                }
                // 购买方完成，冻结转为已完成
                publishService.finish(order.getPublishId(), order);
                // 购买方币增加
                accountInfoService.exchange(select.get(0).getUserId(), order.getCount());
            }
            this.execute("update user_order set status = '2',set second_time = '" + System.currentTimeMillis() + "' where id = '" + id + "'");

        } else if (order.getStatus().equals(0)) {
            WpBizException.NEW("订单已完结");
        } else if (order.getStatus() > 2) {
            WpBizException.NEW("交易已取消");
        }
    }

    @Override
    public void clearTimeout() {
        //二十分钟未支付订单设为超时取消
        List<UserOrderDo> select = select("status = 1 and create_time<=" + (System.currentTimeMillis() - 1000L * 60 * 20));
        for (UserOrderDo order : select) {
            cancel(order.getOrderId(), "3");
        }
    }

    @Override
    public WpResult getDetail(String orderId) {
        SqlString sqlString = new SqlString();
        sqlString.add("SELECT O.*,U.USER_ID,U.MOBILE_PREFIX,U.USER_TEL,U.USER_NIKENAME");
        sqlString.add(" FROM USER_ORDER O LEFT JOIN USER_PUBLISH UP ON O.PUBLISH_ID = UP.PUBLISH_ID");
        sqlString.add(" LEFT JOIN PA_USER_INFO U ON O.USER_ID = U.USER_ID");
        sqlString.add(" WHERE O.ORDER_ID = ?");
        UserOrderDo userOrderDo = jdbcSupportTemplate.selectObject(sqlString.build(), new Object[]{orderId}, UserOrderDo.class);
        return new WpResult().success(userOrderDo);
    }
}
